/*
 * This file is part of aion-engine <aion-engine.com>
 *
 * aion-engine is private software: you can redistribute it and or modify
 * it under the terms of the GNU Lesser Public License as published by
 * the Private Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * aion-engine is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser Public License for more details.
 *
 * You should have received a copy of the GNU Lesser Public License
 * along with aion-engine.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.aionengine.gameserver.ai2.handler;

import com.aionengine.gameserver.ai2.AI2Logger;
import com.aionengine.gameserver.ai2.AIState;
import com.aionengine.gameserver.ai2.NpcAI2;
import com.aionengine.gameserver.ai2.event.AIEventType;
import com.aionengine.gameserver.ai2.manager.AttackManager;
import com.aionengine.gameserver.ai2.manager.FollowManager;
import com.aionengine.gameserver.ai2.manager.WalkManager;
import com.aionengine.gameserver.model.gameobjects.Creature;
import com.aionengine.gameserver.model.gameobjects.VisibleObject;

/**
 * @author ATracer
 */
public class TargetEventHandler {

    /**
     * @param npcAI
     */
    public static void onTargetReached(NpcAI2 npcAI) {
        if (npcAI.isLogging()) {
            AI2Logger.info(npcAI, "onTargetReached");
        }

        AIState currentState = npcAI.getState();
        switch (currentState) {
            case FIGHT:
                npcAI.getOwner().getMoveController().abortMove();
                AttackManager.scheduleNextAttack(npcAI);
                if (npcAI.getOwner().getMoveController().isFollowingTarget())
                    npcAI.getOwner().getMoveController().storeStep();
                break;
            case RETURNING:
                npcAI.getOwner().getMoveController().abortMove();
                npcAI.getOwner().getMoveController().recallPreviousStep();
                if (npcAI.getOwner().isAtSpawnLocation())
                    npcAI.onGeneralEvent(AIEventType.BACK_HOME);
                else
                    npcAI.onGeneralEvent(AIEventType.NOT_AT_HOME);
                break;
            case FOLLOWING:
                npcAI.getOwner().getMoveController().abortMove();
                npcAI.getOwner().getMoveController().storeStep();
                break;
            case FEAR:
                npcAI.getOwner().getMoveController().abortMove();
                npcAI.getOwner().getMoveController().storeStep();
                break;
            case WALKING:
                WalkManager.targetReached(npcAI);
                checkAggro(npcAI);
                break;
		default:
			break;
        }
    }

    /**
     * @param npcAI
     */
    public static void onTargetTooFar(NpcAI2 npcAI) {
        if (npcAI.isLogging()) {
            AI2Logger.info(npcAI, "onTargetTooFar");
        }
        switch (npcAI.getState()) {
            case FIGHT:
                AttackManager.targetTooFar(npcAI);
                break;
            case FOLLOWING:
                FollowManager.targetTooFar(npcAI);
                break;
            case FEAR:
                break;
            default:
                if (npcAI.isLogging()) {
                    AI2Logger.info(npcAI, "default onTargetTooFar");
                }
        }
    }

    /**
     * @param npcAI
     */
    public static void onTargetGiveup(NpcAI2 npcAI) {
        if (npcAI.isLogging()) {
            AI2Logger.info(npcAI, "onTargetGiveup");
        }
        VisibleObject target = npcAI.getOwner().getTarget();
        if (target != null) {
            npcAI.getOwner().getAggroList().stopHating(target);
        }
        if (npcAI.isMoveSupported()) {
            npcAI.getOwner().getMoveController().abortMove();
        }
        if (!npcAI.isAlreadyDead())
            npcAI.think();
    }

    /**
     * @param npcAI
     */
    public static void onTargetChange(NpcAI2 npcAI, Creature creature) {
        if (npcAI.isLogging()) {
            AI2Logger.info(npcAI, "onTargetChange");
        }
        if (npcAI.isInState(AIState.FIGHT)) {
            npcAI.getOwner().setTarget(creature);
            AttackManager.scheduleNextAttack(npcAI);
        }
    }

    private static void checkAggro(NpcAI2 npcAI) {
        for (VisibleObject obj : npcAI.getOwner().getKnownList().getKnownObjects().values()) {
            if (obj instanceof Creature) {
                CreatureEventHandler.checkAggro(npcAI, (Creature) obj);
            }
        }
    }
}
